home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 4 / Amiga Tools 4.iso / tools / netzwerk / pronet / pronet20.lha / ProNET / source / device / pronet.device.s
Text File  |  1995-06-22  |  19KB  |  980 lines

  1. **
  2. ** ProNET.DEVICE  Version  2    ©1995 by Michael Krause
  3. ** Most parts totally recoded, only few parts left from V1
  4. **
  5. ** 05-05-95    Started
  6. ** 08-05-95    v35.0
  7. ** 31-05-95    If the pending writes list is not empty before the MainLoop
  8. **        Wait(), we will signal ourselves to call msgREAD! This is
  9. **        because otherwise a timeout while sending would cause the
  10. **        device to hang completely, if the other machine doesn't
  11. **        send something! v35.1
  12. ** 05-06-95    Flags Argument for Driver-Init. v35.2
  13. ** 09-06-95    Getconfigstring uses MEMF_PUBLIC for Read Buffer. v35.3
  14. ** 15-06-95    PNDERR_DRIVERTROUBLE introduced. v35.4
  15.  
  16. VERSION        equ    35
  17. REVISION    equ    4
  18.  
  19. DEBUG        equ    0
  20.  
  21.         include    "A:OSmacros.i"
  22.         include    "exec/exec.i"
  23.         include    "dos/dosextens.i"
  24.         include    "A:ProNET/include/devices/pronet.i"
  25.         include    "exec_lib.i"
  26.         include    "dos_lib.i"
  27.  
  28.         moveq    #-1,d0
  29.         rts
  30.  
  31. ** -----------------------------------------------------------------------
  32. **
  33. **
  34. **
  35. **
  36.  
  37. **
  38. ** Library/Device Base Structures
  39. **
  40.  
  41. **
  42. **
  43. **
  44. **
  45. ** -----------------------------------------------------------------------
  46.  
  47.         STRUCTURE MyDev,LIB_SIZE    ;Device Base
  48.         APTR    pnd_SegList
  49.         APTR    pnd_DosBase
  50.         LABEL   pnd_SizeOf
  51.  
  52.         STRUCTURE MyUnit,0        ;Unit Structure
  53.         APTR    pndu_Next
  54.         ULONG    pndu_UnitNr
  55.         APTR    pndu_ProcessID
  56.         APTR    pndu_MsgPort
  57.         LABEL    pndu_SizeOf
  58.  
  59.         STRUCTURE PortMember,0        ;One Port of a Unit
  60.         APTR    pndp_Next
  61.         UWORD    pndp_PortNr
  62.         ULONG    pndp_MsgPort
  63.         LABEL    pndp_SizeOf
  64.  
  65. PND_ADDPORT    equ    5
  66. PND_REMPORT    equ    6
  67.  
  68. LibResident    dc.w    RTC_MATCHWORD
  69.         dc.l    LibResident
  70.         dc.l    EndResident
  71.         dc.b    RTF_AUTOINIT
  72.         dc.b    VERSION
  73.         dc.b    NT_DEVICE
  74.         dc.b    0
  75.         dc.l    DevName
  76.         dc.l    IDString
  77.         dc.l    LibInitData
  78.  
  79. DevName        dc.b    "pronet.device",0
  80.         dc.b    "$VER: "
  81. IDString    dc.b    "pronet.device "
  82.         dc.b    (VERSION/10)+48,(VERSION-((VERSION/10)*10))+48,".",REVISION+48
  83.         dc.b    " (09-06-95)",13,10,0
  84.         even
  85.  
  86. LibInitData    dc.l    pnd_SizeOf
  87.         dc.l    FuncTab
  88.         dc.l    DataTab
  89.         dc.l    LibInitRout
  90.  
  91. FuncTab        dc.l    Open
  92.         dc.l    Close
  93.         dc.l    Expunge
  94.         dc.l    ExtFunc
  95.         dc.l    BeginIO
  96.         dc.l    AbortIO
  97.         dc.l    getconfigstr
  98.         dc.l    freeconfigstr
  99.         dc.l    -1
  100.  
  101. DataTab        INITBYTE   LN_TYPE,NT_DEVICE
  102.         INITLONG   LN_NAME,DevName
  103.         INITBYTE   LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED
  104.         INITWORD   LIB_VERSION,VERSION
  105.         INITWORD   LIB_REVISION,REVISION
  106.         INITLONG   LIB_IDSTRING,IDString
  107.         dc.w    0
  108.  
  109. OurBase        dc.l    0
  110.  
  111. ** -----------------------------------------------------------------------
  112. **
  113. **
  114. **
  115. **
  116.  
  117. **
  118. ** Library/Device Base Routines
  119. **
  120.  
  121. **
  122. **
  123. **
  124. **
  125. ** -----------------------------------------------------------------------
  126.  
  127. ; -- Called once when the device was loaded
  128. LibInitRout    movem.l    d1-d7/a0-a6,-(sp)
  129.         move.l    d0,a5
  130.         move.l    a5,OurBase
  131.         move.l    a0,pnd_SegList(a5)
  132.  
  133.         lea    dosname(pc),a1
  134.         moveq    #0,d0
  135.         LIBCALL    OpenLibrary
  136.         move.l    d0,pnd_DosBase(a5)
  137.  
  138.         move.l    a5,d0
  139.         movem.l    (sp)+,d1-d7/a0-a6
  140.         rts
  141.  
  142. ; -- This piece is called by OpenDevice()
  143. Open        movem.l    a2-a6/d2-d7,-(sp)
  144.         addq.w    #1,LIB_OPENCNT(a6)
  145.         move.l    d0,d6            ;Unit
  146.         move.l    a1,a2            ;IORequest
  147.         move.l    a6,a5            ;DevBase
  148.  
  149.         move.b    #IOERR_OPENFAIL,IO_ERROR(a2)
  150.  
  151.         * Does the required Unit already exist?
  152.         lea    unitlist(pc),a3
  153. .searchunit    move.l    (a3),d0
  154.         beq.s    .newunit
  155.         move.l    d0,a3
  156.         cmp.l    pndu_UnitNr(a3),d6
  157.         bne.s    .searchunit
  158.         bra.s    .unitok
  159.  
  160.         * No! So create a Unit!
  161. .newunit    bsr    InitUnit
  162.         tst.l    d0
  163.         beq    .ende
  164.         move.l    d0,a3
  165.  
  166.         * Yes! Add new port now! Unit-Structure in a3
  167. .unitok        move.l    4.w,a6
  168.         move.w    #PND_ADDPORT,IO_COMMAND(a2)
  169.         move.l    a2,a1
  170.         move.l    pndu_MsgPort(a3),a0
  171.         LIBCALL    PutMsg
  172.         move.l    a2,a1
  173.         LIBCALL    WaitIO
  174.         tst.b    d0
  175.         bne.s    .ende
  176.  
  177.         move.l    a3,IO_UNIT(a2)
  178.  
  179.         * Device successfully opened.
  180.         move.l    a5,a6
  181.         bclr    #LIBB_DELEXP,LIB_FLAGS(a6)
  182.         addq.w    #1,LIB_OPENCNT(a6)
  183.         move.b    #NT_REPLYMSG,LN_TYPE(a2)
  184.         clr.b    IO_ERROR(a2)
  185.  
  186. .ende        move.l    a5,a6
  187.         subq.w    #1,LIB_OPENCNT(a6)
  188.         move.b    IO_ERROR(a2),d0
  189.         beq.s    .0
  190.         move.l    #-1,IO_DEVICE(a2)
  191. .0        movem.l    (sp)+,a2-a6/d2-d7
  192.         rts
  193.  
  194. ; -- Called by CloseDevice()
  195. Close        movem.l    a2/a5,-(sp)
  196.         move.l    a1,a2
  197.         move.l    a6,a5
  198.  
  199.         move.l    4.w,a6
  200.         move.l    IO_UNIT(a1),a0
  201.         move.l    pndu_MsgPort(a0),a0
  202.         move.w    #PND_REMPORT,IO_COMMAND(a1)
  203.         LIBCALL    PutMsg
  204.         move.l    a2,a1
  205.         LIBCALL    WaitIO
  206.  
  207.         move.l    a2,a1
  208.         move.l    a5,a6
  209.         move.l    #-1,IO_DEVICE(a1)
  210.         move.l    #-1,IO_UNIT(a1)
  211.  
  212.         subq.w    #1,LIB_OPENCNT(a6)
  213.         moveq    #0,d0
  214.         movem.l    (sp)+,a2/a5
  215.         rts
  216.  
  217. ; -- This routine was kept free by Commodore for about 10 years now ;)
  218. ExtFunc        moveq    #0,d0
  219.         rts
  220.  
  221. ; -- Application wants an IORequest to be executed
  222. BeginIO        move.l    a6,-(sp)
  223.         move.b    #NT_MESSAGE,LN_TYPE(a1)
  224.         bclr    #0,IO_FLAGS(a1)        ;Clear IOF_QUICK
  225.         clr.b    IO_ERROR(a1)
  226.         move.l    IO_UNIT(a1),a0
  227.         move.l    pndu_MsgPort(a0),a0
  228.         move.l    4.w,a6
  229.         LIBCALL    PutMsg
  230.         moveq    #0,d0
  231.         move.l    (sp)+,a6
  232.         rts
  233.  
  234. ; -- AbortIO is not supported
  235. AbortIO        moveq    #0,d0            ;Gar nix geht ab hier.
  236.         rts
  237.  
  238. ; -- Called e.g. when memory is low and the device is not used anymore.
  239. Expunge        movem.l    d1-d2/a1-a6,-(sp)
  240.         moveq    #0,d0
  241.         bset    #LIBB_DELEXP,LIB_FLAGS(a6)    ;we don't support
  242.         movem.l    (sp)+,d1-d2/a1-a6        ;expunging!
  243.         rts
  244.  
  245. ; -- Create new Unit
  246. InitUnit    ; a5 *DevBase
  247.         ; a2 *IORequest
  248.         ; d6 Unit
  249.         ; RETURNS d0 *Unit-Structure or NULL
  250.         move.l    4.w,a6
  251.         moveq    #pndu_SizeOf,d0
  252.         moveq    #MEMF_PUBLIC,d1
  253.         LIBCALL    AllocMem
  254.         tst.l    d0
  255.         beq.s    .ende
  256.         move.l    d0,a3
  257.  
  258.         move.l    d6,pndu_UnitNr(a3)
  259.  
  260.         * First, create Unit process
  261.         move.l    pnd_DosBase(a5),a6    ;We will break the Forbid()
  262.         move.l    #DevName,d1        ;which EXEC made for us;
  263.         moveq    #0,d2            ;it's okay because we have
  264.         move.l    #ProcessCode-4,d3    ;all variables in registers,
  265.         lsr.l    #2,d3            ;so our routine can be run
  266.         move.l    #4096,d4        ;twice at one time without
  267.         LIBCALL    CreateProc        ;problems!
  268.         move.l    d0,d7
  269.         beq.s    .ende
  270.  
  271.         move.l    d7,pndu_ProcessID(a3)
  272.  
  273.         * Notify process about Unit number
  274.         move.l    4.w,a6
  275.         move.l    a2,a1
  276.         move.l    a3,pnr_Data2(a1)
  277.         move.b    IO_ERROR(a2),d2        ;save it for the main routine
  278.         move.l    d7,a0
  279.         LIBCALL    PutMsg
  280.  
  281.         * Wait for Process to finish initialization
  282.         move.l    a2,a1
  283.         LIBCALL    WaitIO
  284.         move.b    d2,IO_ERROR(a2)
  285.         tst.b    d0
  286.         bne.s    .error
  287.  
  288.         * Now add this Unit-Structure to our internal List!!
  289.         LIBCALL    Forbid            ;<< important!
  290.         lea    unitlist(pc),a0
  291.         move.l    (a0),(a3)
  292.         move.l    a3,(a0)
  293.         LIBCALL    Permit
  294.  
  295.         move.l    a3,d0
  296.         rts
  297.  
  298. .error        move.l    4.w,a6            ;Process will terminate
  299.         move.l    a3,a1            ;itself in case of an error
  300.         moveq    #pndu_SizeOf,d0
  301.         LIBCALL    FreeMem
  302. .ende        moveq    #0,d0
  303.         rts
  304.  
  305. unitlist    dc.l    0        ;List of all Units loaded!
  306.  
  307. ** -----------------------------------------------------------------------
  308. **
  309. **
  310. **
  311. **
  312.  
  313. **
  314. ** DeviceUnit Process Code
  315. **
  316.  
  317. **
  318. **
  319. **
  320. **
  321. ** -----------------------------------------------------------------------
  322.  
  323.         cnop    0,4
  324.  
  325.         STRUCTURE PrivateData,0
  326.         APTR    priv_OurUnit
  327.         STRUCT    priv_ConfigStringName,30
  328.         APTR    priv_ConfigString
  329.         STRUCT    priv_DriverName,30
  330.  
  331.         LABEL    priv_DriverData
  332.         UBYTE    priv_ReadSignalBit
  333.         UBYTE    priv_pad0
  334.         APTR    priv_ReadQuery
  335.         APTR    priv_Read
  336.         APTR    priv_Write
  337.  
  338.         APTR    priv_MsgPort
  339.         APTR    priv_MsgBackPort
  340.         APTR    priv_PortList
  341.         STRUCT    priv_PendingReads,12
  342.         STRUCT    priv_PendingWrites,12
  343.         LABEL    priv_SizeOf
  344.  
  345. ProcessCode    move.l    4.w,a6
  346.         move.l    ThisTask(a6),a2
  347.         lea    pr_MsgPort(a2),a2
  348.         move.l    a2,a0
  349.         LIBCALL    WaitPort
  350.         move.l    a2,a0
  351.         LIBCALL    GetMsg
  352.         move.l    d0,a3
  353.  
  354.         move.b    #IOERR_OPENFAIL,IO_ERROR(a3)    ;[a3] Startupmsg
  355.  
  356.         * Get memory for private data
  357.         moveq    #priv_SizeOf,d0
  358.         move.l    #MEMF_CLEAR,d1
  359.         LIBCALL    AllocMem
  360.         tst.l    d0
  361.         beq    .ende
  362.         move.l    d0,a5
  363.  
  364.         lea    priv_PendingReads(a5),a1
  365.         NEWLIST    a1
  366.         lea    priv_PendingWrites(a5),a1
  367.         NEWLIST    a1
  368.  
  369.         * Get port for messages replied from the application
  370.         bsr    CreatePort
  371.         move.l    d0,priv_MsgBackPort(a5)
  372.         beq.s    .noconf
  373.  
  374.         bsr    CreatePort
  375.         move.l    d0,priv_MsgPort(a5)
  376.         beq.s    .noport2
  377.  
  378.         move.l    pnr_Data2(a3),a0
  379.         move.l    a0,priv_OurUnit(a5)
  380.         move.l    priv_MsgPort(a5),pndu_MsgPort(a0)
  381.  
  382.         * Get configuration string for our unit
  383.         move.l    pndu_UnitNr(a0),d0
  384.         lea    confstr(pc),a1
  385.         lea    priv_ConfigStringName(a5),a0
  386. .l0        move.b    (a1)+,(a0)+
  387.         bne.s    .l0
  388.         subq.l    #1,a0
  389.         bsr    long2dec
  390.         move.b    #":",(a0)+
  391.         clr.b    (a0)
  392.         lea    priv_ConfigStringName(a5),a0
  393.         bsr    getconfigstr
  394.         move.l    d0,priv_ConfigString(a5)
  395.         beq.s    .noconf
  396.  
  397.         move.b    #PNDERR_DRIVERTROUBLE,IO_ERROR(a3)
  398.         bsr    StartDriver
  399.         tst.l    d0
  400.         beq.s    .noconf
  401.  
  402.         clr.b    IO_ERROR(a3)
  403.         move.l    a3,a1
  404.         LIBCALL    ReplyMsg
  405.  
  406.         bra    MainLoop
  407.  
  408. .noport2    move.l    priv_MsgBackPort(a5),a0
  409.         bsr    DeletePort
  410. .noconf        move.l    a5,a1
  411.         moveq    #priv_SizeOf,d0
  412.         LIBCALL    FreeMem
  413. .ende        move.l    a3,a1
  414.         LIBCALL    ReplyMsg
  415.         rts
  416.  
  417. confstr        dc.b    "pronet-device-",0
  418.         even
  419.  
  420. ; -- Load the interface driver and initialize it.
  421. StartDriver    ; RETURNS d0 NULL on failure!
  422.         movem.l    a2/a6,-(sp)
  423.         lea    priv_DriverName(a5),a1
  424.         move.l    a1,d1
  425.         lea    drivername(pc),a0
  426. .l0        move.b    (a0)+,(a1)+
  427.         bne.s    .l0
  428.         subq.l    #1,a1
  429.         move.l    priv_ConfigString(a5),a0
  430. .l1        move.b    (a0)+,d0
  431.         move.b    d0,(a1)+
  432.         cmp.b    #" ",d0
  433.         bhi.s    .l1
  434.         clr.b    -(a1)
  435.         move.l    a0,d6
  436.  
  437.         move.l    OurBase(pc),a6        ;naahh why should I open
  438.         move.l    pnd_DosBase(a6),a6    ;it again??
  439.         LIBCALL    LoadSeg
  440.         add.l    d0,d0
  441.         add.l    d0,d0
  442.         beq.s    .error
  443.         addq.l    #4,d0
  444.         move.l    d0,a2
  445.  
  446.         * And now, Ladies & Gentlemen :))
  447.         lea    priv_DriverData(a5),a0
  448.         move.l    d6,a1        ;ConfString after Driver-ID
  449.         move.l    #"RST!",d0
  450.         moveq    #0,d1
  451.         jsr    (a2)
  452.         tst.l    d0
  453.         beq.s    .error
  454.  
  455.         moveq    #-1,d0
  456.         bra.s    .ende
  457.  
  458. .error        moveq    #0,d0
  459. .ende        movem.l    (sp)+,a2/a6
  460.         rts
  461.  
  462. drivername    dc.b    "DEVS:ProNET/",0
  463.         even
  464.  
  465.  
  466. ******************
  467. ; -- The Main Loop
  468. ******************
  469.  
  470. MainLoop    move.l    priv_MsgBackPort(a5),a0
  471.         move.b    MP_SIGBIT(a0),d2
  472.         move.b    priv_ReadSignalBit(a5),d3
  473.         move.l    priv_MsgPort(a5),a0
  474.         move.b    MP_SIGBIT(a0),d4
  475.         moveq    #0,d5
  476.         bset    d2,d5
  477.         bset    d3,d5
  478.         bset    d4,d5            ;[d5] Signalmask to wait for
  479.         movem.l    a6/d2-d5,-(sp)
  480.  
  481. Wait4Msg    movem.l    (sp),a6/d2-d5
  482.         bsr    CheckWrites
  483.         move.l    d5,d0
  484.         LIBCALL    Wait
  485.         movem.l    d0/d3/d4,-(sp)
  486.         btst    d2,d0
  487.         bne    doMSGBACK
  488. wait1        movem.l    (sp),d0/d3/d4
  489.         btst    d3,d0
  490.         bne    doREAD
  491. wait2        movem.l    (sp)+,d0/d3/d4
  492.         btst    d4,d0
  493.         bne    doMSG
  494.         bra    Wait4Msg
  495.  
  496. ; -- New Message at our MsgPort
  497. doMSG        move.l    priv_MsgPort(a5),a0
  498.         LIBCALL    GetMsg
  499.         tst.l    d0
  500.         beq    Wait4Msg        ;no more messages
  501.         move.l    d0,a2
  502.         move.w    IO_COMMAND(a2),d0
  503.  
  504.         cmp.w    #PND_WRITE,d0
  505.         beq    doWRITE
  506.         cmp.w    #PND_ADDPORT,d0
  507.         beq    doADDPORT
  508.         cmp.w    #PND_REMPORT,d0
  509.         beq    doREMPORT
  510.  
  511.         move.b    #IOERR_NOCMD,IO_ERROR(a2)
  512.         move.l    a2,a1
  513.         LIBCALL    ReplyMsg
  514.         bra    doMSG
  515.  
  516. ; -- Add a new port to this unit
  517. doADDPORT    move.w    pnr_NetSourcePort(a2),d1
  518.         cmp.w    #-1,d1
  519.         beq    addport_getconf
  520.         cmp.w    #-2,d1
  521.         beq    addport_getnext
  522.  
  523.         move.b    #IOERR_OPENFAIL,IO_ERROR(a2)
  524.  
  525.         * See if port already exists, portnumber in d1 now
  526.         lea    priv_PortList(a5),a0
  527. .loop0        move.l    (a0),d0
  528.         beq.s    .ok
  529.         move.l    d0,a0
  530.         cmp.w    pndp_PortNr(a0),d1
  531.         bne.s    .loop0
  532.         * Sorry
  533.         move.b    #PNDERR_PORTEXISTS,IO_ERROR(a2)
  534.         bra.s    addport_ende
  535.  
  536.         * No, add it!
  537. .ok        moveq    #pndp_SizeOf,d0
  538.         moveq    #0,d1
  539.         LIBCALL    AllocMem
  540.         tst.l    d0
  541.         beq.s    addport_ende
  542.  
  543.         move.l    d0,a4
  544.         move.w    pnr_NetSourcePort(a2),pndp_PortNr(a4)
  545.         move.l    pnr_MsgPort(a2),pndp_MsgPort(a4)
  546.         lea    priv_PortList(a5),a0
  547.         move.l    (a0),(a4)
  548.         move.l    a4,(a0)
  549.  
  550.         bsr    TryPendingReads
  551.  
  552.         clr.b    IO_ERROR(a2)        ;Okay, port added
  553. addport_ende    move.l    a2,a1
  554.         LIBCALL    ReplyMsg
  555.         bra    doMSG
  556.  
  557. addport_getconf    move.l    pnr_Data1(a2),a0
  558.         bsr    getconfigstr
  559.         move.l    d0,d3
  560.         beq.s    .nostring
  561.         move.l    d0,a0
  562.         bsr    dec2long
  563.         move.w    d1,pnr_NetSourcePort(a2)
  564.         move.l    d3,a0
  565.         bsr    freeconfigstr
  566.         bra    doADDPORT
  567. .nostring    move.b    #PNDERR_BADCONFIG,IO_ERROR(a2)
  568.         bra.s    addport_ende
  569.  
  570. addport_getnext    moveq    #1,d1
  571.         lea    priv_PortList(a5),a1
  572. .next        move.l    a1,a0
  573. .loop0        move.l    (a0),d0
  574.         beq.s    .notfound
  575.         move.l    d0,a0
  576.         cmp.w    pndp_PortNr(a0),d1
  577.         bne.s    .loop0
  578.         addq.w    #1,d1
  579.         bra.s    .next
  580. .notfound    move.w    d1,pnr_NetSourcePort(a2)
  581.         bra    doADDPORT
  582.  
  583. ; -- Remove current port
  584. doREMPORT    move.w    pnr_NetSourcePort(a2),d2
  585.         lea    priv_PortList(a5),a1
  586. .find        move.l    a1,a3
  587.         move.l    (a1),d0
  588.         beq.s    .notfound
  589.         move.l    d0,a1
  590.         cmp.w    pndp_PortNr(a1),d2
  591.         bne.s    .find
  592.         move.l    (a1),d2
  593.         moveq    #pndp_SizeOf,d0
  594.         LIBCALL    FreeMem
  595.         move.l    d2,(a3)        ;Teil aus der Liste entfernt !!
  596.         move.l    a2,a1
  597.         LIBCALL    ReplyMsg
  598. .notfound    bra    doMSG
  599.  
  600. ; -- Do a WRITE command
  601. doWRITE        move.l    a2,a1
  602.         lea    priv_PendingWrites(a5),a0
  603.         LIBCALL    AddTail
  604.         bsr    TryPendingWrites
  605.         bra    doMSG            ;kurz und schmerzlos :-)
  606.  
  607. ; -- A ProNET-Message was replied
  608. doMSGBACK    move.l    priv_MsgBackPort(a5),a0
  609.         LIBCALL    GetMsg
  610.         tst.l    d0
  611.         beq    wait1
  612.         move.l    d0,a1            ;we don't need it any more.
  613.         moveq    #0,d0
  614.         move.w    MN_LENGTH(a1),d0
  615.         add.l    #MN_SIZE,d0
  616.         LIBCALL    FreeMem
  617.         bra.s    doMSGBACK
  618.  
  619. ; -- A new message from another Amiga is ready
  620. doREAD        move.l    priv_ReadQuery(a5),a0    ;Do external driver magic..
  621.         jsr    (a0)
  622.  
  623.         * d0.w length (if NULL then exit!!!)
  624.         * d1 destination port
  625.         * d2 source port
  626.         ext.l    d0
  627.         beq.s    .ende
  628.         move.w    d1,d7
  629.         move.w    d2,d5
  630.         move.l    d0,d6
  631.         addq.w    #2,d6    ;include Source Port word
  632.  
  633.         add.l    #MN_SIZE+2,d0
  634.         move.l    d0,d3
  635. .tryagain    moveq    #MEMF_PUBLIC,d1        ;This part is the one and
  636.         LIBCALL    AllocMem        ;only thing in this device
  637.         tst.l    d0            ;which I don't like, but
  638.         bne.s    .memok            ;it's the only solution!
  639.         move.l    OurBase(pc),a6
  640.         move.l    pnd_DosBase(a6),a6
  641.         moveq    #50,d1
  642.         LIBCALL    Delay
  643.         move.l    4.w,a6
  644.         move.l    d3,d0
  645.         bra.s    .tryagain
  646.  
  647.         * Now get the data and build a Message
  648. .memok        move.l    d0,a3
  649.         lea    MN_SIZE+2(a3),a0
  650.         move.l    priv_Read(a5),a1
  651.         jsr    (a1)
  652.         move.w    d5,MN_SIZE(a3)
  653.         move.w    d6,MN_LENGTH(a3)
  654.         move.w    d7,LN_NAME(a3)
  655.         move.l    priv_MsgBackPort(a5),MN_REPLYPORT(a3)
  656.         move.b    #NT_MESSAGE,LN_TYPE(a3)
  657.  
  658.         lea    priv_PendingReads(a5),a0
  659.         move.l    a3,a1
  660.         LIBCALL    AddTail
  661.  
  662. .ende        bsr    TryPendingReads
  663.         bsr    TryPendingWrites
  664.         bra    wait2
  665.  
  666. ***
  667. ***
  668. ***
  669.  
  670. ; -- Look at the history, 31-05-95 for reasons why we do this!
  671. CheckWrites    lea    priv_PendingWrites(a5),a0
  672.         TSTLIST    a0
  673.         beq.s    .okay
  674.         move.b    priv_ReadSignalBit(a5),d0
  675.         moveq    #0,d1
  676.         bset    d0,d1
  677.         moveq    #-1,d0
  678.         LIBCALL    SetSignal
  679. .okay        rts
  680.  
  681. ***
  682. ***
  683. ***
  684.  
  685. ; -- Try to send off all pending messages
  686. TryPendingReads    move.l    a2,-(sp)
  687.         lea    priv_PendingReads(a5),a3
  688.         move.l    LH_HEAD(a3),a2
  689.         addq.l    #4,a3
  690. .looop        cmp.l    a2,a3
  691.         bne.s    .doit
  692.         move.l    (sp)+,a2
  693.         rts
  694.  
  695. .doit        move.l    a2,a4
  696.         move.l    LN_SUCC(a2),a2
  697.  
  698.         move.w    LN_NAME(a4),d1
  699.         lea    priv_PortList(a5),a0
  700. .find        move.l    (a0),d0
  701.         beq.s    .looop
  702.         move.l    d0,a0
  703.         cmp.w    pndp_PortNr(a0),d1
  704.         bne.s    .find
  705.         move.l    pndp_MsgPort(a0),d5
  706.         move.l    a4,a1
  707.         LIBCALL    Remove
  708.         move.l    d5,a0
  709.         move.l    a4,a1
  710.         LIBCALL    PutMsg
  711.         bra.s    .looop
  712.  
  713. ; -- Try to send off all pending write requests
  714. TryPendingWrites
  715.         move.l    a2,-(sp)
  716.         lea    priv_PendingWrites(a5),a3
  717.         move.l    LH_HEAD(a3),a2
  718.         addq.l    #4,a3
  719. .looop        cmp.l    a2,a3
  720.         bne.s    .doit
  721. .busy        move.l    (sp)+,a2
  722.         rts
  723.  
  724. .doit        move.l    a2,a4
  725.         move.l    LN_SUCC(a2),a2
  726.  
  727.         move.l    pnr_Data1(a4),a0
  728.         move.l    pnr_Length1(a4),d0
  729.         addq.l    #1,d0            ;round up to word boundary
  730.         bclr    #0,d0
  731.         move.l    pnr_Data2(a4),a1
  732.         move.l    pnr_Length2(a4),d1
  733.         addq.l    #1,d1            ;dito
  734.         bclr    #0,d1
  735.         move.w    pnr_NetDestPort(a4),d2
  736.         move.w    pnr_NetSourcePort(a4),d3
  737.         move.l    priv_Write(a5),a6
  738.         jsr    (a6)            ;Again some driver magic..
  739.         move.l    4.w,a6
  740.         tst.w    d0
  741.         bne.s    .busy
  742.  
  743.         * IORequest done, reply it!
  744.         move.l    a4,a1
  745.         LIBCALL    Remove
  746.         move.l    a4,a1
  747.         LIBCALL    ReplyMsg
  748.         bra.s    .looop
  749.  
  750. ** -----------------------------------------------------------------------
  751. **
  752. **
  753. **
  754. **
  755.  
  756. **
  757. ** Routines for handling the configuration file
  758. **
  759.  
  760. **
  761. **
  762. **
  763. **
  764. ** -----------------------------------------------------------------------
  765.  
  766. ; -- Obtain configuration string
  767. getconfigstr    ; a0 *line-identifier (e.g. 'HD2:') with ':'
  768.         ; RETURNS d0 *line-string or NULL if it doesn't exist
  769.         movem.l    d2-d7/a2-a6,-(sp)
  770.         move.l    a0,a2
  771.         moveq    #0,d4            ;RC
  772.  
  773.         move.l    4.w,a6
  774.         move.l    #$104,d0
  775.         moveq    #0,d1
  776.         LIBCALL    AllocMem
  777.         move.l    d0,d6            ;Allocate FIB
  778.         beq    .error
  779.         move.l    OurBase(pc),a5
  780.         move.l    pnd_DosBase(a5),a5
  781.         move.l    a5,a6
  782.         move.l    #configname,d1
  783.         moveq    #ACCESS_READ,d2
  784.         LIBCALL    Lock
  785.         move.l    d0,d7
  786.         beq    .nolock.mem
  787.         move.l    d7,d1
  788.         move.l    d6,d2
  789.         LIBCALL    Examine
  790.         move.l    d7,d1
  791.         LIBCALL    UnLock            ;So we've got the file length
  792.  
  793.         move.l    4.w,a6
  794.         move.l    d6,a0
  795.         move.l    fib_Size(a0),d0
  796.         addq.l    #1,d0
  797.         move.l    d0,d5            ;[d5] configmemsize
  798.         move.l    #MEMF_PUBLIC^MEMF_CLEAR,d1
  799.         LIBCALL    AllocMem
  800.         tst.l    d0
  801.         beq    .nolock.mem
  802.         move.l    d0,a3            ;[a3] configmem
  803.         move.l    a3,a4
  804.  
  805.         move.l    a5,a6            ;Read file
  806.         move.l    #configname,d1
  807.         move.l    #MODE_OLDFILE,d2
  808.         LIBCALL    Open
  809.         move.l    d0,d7
  810.         beq.s    .nofile
  811.         move.l    d7,d1
  812.         move.l    a3,d2
  813.         move.l    d5,d3
  814.         subq.l    #1,d3
  815.         LIBCALL    Read
  816.         move.l    d0,d2
  817.         move.l    d7,d1
  818.         LIBCALL    Close
  819.         cmp.l    d2,d3
  820.         bne.s    .nofile
  821.  
  822. .loop        move.l    a2,a0            ;Search string
  823.         move.l    a3,a1
  824.         bsr.s    .comparestr
  825.         tst.w    d0
  826.         bne.s    .next
  827.  
  828. .search0    move.b    (a1)+,d0        ;Skip spaces until first
  829.         beq.s    .nofile            ;character
  830.         cmp.b    #10,d0
  831.         beq.s    .nofile
  832.         cmp.b    #32,d0
  833.         bls.s    .search0
  834.  
  835.         move.l    a1,d2            ;Get length of string
  836.         subq.l    #1,d2
  837.         moveq    #-5,d0
  838. .search1    move.b    (a1)+,d1
  839.         beq.s    .searchok
  840.         cmp.b    #10,d1
  841.         beq.s    .searchok
  842.         dbra    d0,.search1
  843.  
  844. .searchok    neg.l    d0            ;Extract string
  845.         move.l    d0,d3
  846.         move.l    4.w,a6
  847.         moveq    #MEMF_PUBLIC,d1
  848.         LIBCALL    AllocMem
  849.         tst.l    d0
  850.         beq.s    .nofile
  851.         move.l    d0,a0
  852.         move.l    d3,(a0)+
  853.         move.l    a0,d4
  854.         move.l    d2,a1
  855. .copyl0        move.b    (a1)+,d1
  856.         move.b    d1,(a0)+
  857.         beq.s    .copyok
  858.         cmp.b    #10,d1
  859.         bne.s    .copyl0
  860. .copyok        clr.b    -(a0)
  861.         bra.s    .nofile
  862.  
  863. .next        bsr.s    .nextline
  864.         tst.w    d0
  865.         beq.s    .loop
  866.  
  867. .nofile        move.l    4.w,a6
  868.         move.l    a4,a1
  869.         move.l    d5,d0
  870.         LIBCALL    FreeMem
  871. .nolock.mem    move.l    4.w,a6
  872.         move.l    d6,a1
  873.         move.l    #$104,d0
  874.         LIBCALL    FreeMem
  875.  
  876. .error        move.l    d4,d0
  877. .ende        movem.l    (sp)+,d2-d7/a2-a6
  878.         rts
  879.  
  880. .comparestr    moveq    #0,d0
  881. .compl0        move.b    (a0)+,d1
  882.         move.b    (a1)+,d2
  883.         bclr    #5,d1
  884.         bclr    #5,d2
  885.         cmp.b    d1,d2
  886.         bne.s    .comperr
  887.         tst.b    d1
  888.         beq.s    .compok
  889.         bra.s    .compl0
  890. .comperr    moveq    #-1,d0
  891. .compok        rts
  892.  
  893. .nextline    moveq    #0,d0
  894.         move.b    (a3)+,d1
  895.         beq.s    .nextlerr
  896.         cmp.b    #10,d1
  897.         beq.s    .nextlok
  898.         bra.s    .nextline
  899. .nextlerr    moveq    #-1,d0        ;end of file
  900. .nextlok    rts
  901.  
  902. ; -- Dispose configuration string
  903. freeconfigstr    ; a0 *line-string got by 'getconfigstr'
  904.         move.l    a6,-(sp)
  905.         move.l    -(a0),d0
  906.         move.l    a0,a1
  907.         move.l    4.w,a6
  908.         LIBCALL    FreeMem
  909.         move.l    (sp)+,a6
  910.         rts
  911.  
  912. configname    dc.b    "DEVS:ProNET.config",0
  913. dosname        dc.b    "dos.library",0
  914.         even
  915.  
  916.  
  917. ** -----------------------------------------------------------------------
  918. **
  919. **
  920. **
  921. **
  922.  
  923. **
  924. ** Useful routines
  925. **
  926.  
  927. **
  928. **
  929. **
  930. **
  931. ** -----------------------------------------------------------------------
  932.  
  933. dec2long    ; konvertiert Dezimalstring ab (a0) zu Longword in D1 !!
  934.         moveq    #0,d1
  935. .loop        moveq    #0,d0
  936.         move.b    (a0)+,d0
  937.         sub.b    #"0",d0
  938.         cmp.b    #9,d0
  939.         bhi.s    .oki
  940.         move.l    d1,d2
  941.         lsl.l    #3,d1
  942.         add.l    d2,d1
  943.         add.l    d2,d1
  944.         add.l    d0,d1
  945.         bra.s    .loop
  946. .oki        rts
  947.  
  948. long2dec    ;Converts Long in d0 to Dec-String in (a0)+
  949.         tst.l    d0
  950.         bne.s    .0
  951.         move.b    #"0",(a0)+
  952.         rts
  953. .0        lea    long2asciitab(pc),a1
  954.         moveq    #9,d1
  955.         moveq    #0,d6
  956. .1        move.l    (a1)+,d2
  957.         move.l    d0,d3
  958.         moveq    #-1,d4
  959. .2        move.l    d3,d5
  960.         sub.l    d2,d3
  961.         cmp.l    d5,d3
  962.         dbhi    d4,.2
  963.         add.l    d2,d3
  964.         move.l    d3,d0
  965.         not.w    d4
  966.         bne.s    .3
  967.         tst.w    d6
  968.         beq.s    .4
  969. .3        st    d6
  970.         add.b    #"0",d4
  971.         move.b    d4,(a0)+
  972. .4        dbra    d1,.1
  973.         rts
  974. long2asciitab    dc.l    1000000000,100000000,10000000,1000000,100000
  975.         dc.l    10000,1000,100,10,1
  976.  
  977.         include    "A:ProNET/source/devio.s"
  978.  
  979. EndResident:
  980.